package chapter02

/**
 * @program lu-scala01
 * @description: lambda
 * @author: zhanglu
 * @create: 2022-02-13 19:00:00
 */
object C06_Lambda {

  def main(args: Array[String]): Unit = {
    test04
  }

  def test01 {
    //匿名函数，lambda表达式
    //9.如果不关心名称，只关心逻辑处理，那么函数名 def 可以省略
    val f1 = (name: String) => {
      println(name)
    }
    //定义一个函数，以函数作为参数输入
    def f2(fun: String => Unit, name: String){
      fun(name)
    }
    f2(f1, "lu1")
    f2((name: String) => {println(name + "_")}, "lu1")

    //匿名函数的简化
    //1.参数的类型可以省略，会根据形参进行自动推导
    //2.类型省略后，发现只有一个参数，则()括号可以省略，其他情况，没有参数和参数超过1的永远不能省略括号
    f2(name => {println(name + "__")}, "lu1");
    //3.匿名函数如果只有一行，大括号可以省略
    f2(name => println(name + "__"), "lu1");
    //4.如果参数只出现一次，则参数省略且后面参数可用_代替
    f2(println(_), "lu2 ");
    //5.如果推断出，当前传入的println是一个函数体，而不是调用语句，可以直接省略下划线
    f2(println, "lu3")
  }

  def test02 {
    val addOp = (a: Int, b: Int) => a + b

    def twoVarOpFunc(fun: (Int, Int) => Int, a: Int, b: Int): Int = {
      fun(a, b)
    }

    var res = twoVarOpFunc(addOp, 1, 1)
    println(res)

    res = twoVarOpFunc((a, b) => a + b, 1, 2)
    println(res)

    res = twoVarOpFunc(_ + _, 1, 3)
    println(res)
  }

  def test03  {

    def f(n: Int) = {
      println("n:" + n)
      n + 1
    }

    val res = f(123)
    println(res)

    val res1 = f _
    println(res1)
    println(res1(1))

    val res2: Int => Int = f
    println(res2)
    println(res2(2))

    def fun() = {
      1
    }
    val rs = fun
    println(fun)
    val rs1 = fun _
    println(rs1)
    println(rs1())

    val rs2: () => Int = fun
    println(rs2)
    println(rs2())

  }

  /**
   * 函数作为方法的返回值返回
   */
  def test04 {
    def f(): Int => Int = {
      def f1(n: Int): Int = {
        n + 1
      }
      f1
    }
    println(f)
    println(f()(1))
    val f2 = f
    println(f2(2))

  }

}
